/**
 * @class NG.controllers.MapView 
 * @extends Ext.Controller
 * 
 * This controller handles events and commands for map view {@link NG.views.MapView}.
 * 
 */
NG.controllers.MapView = Ext.extend(Ext.Controller, {
	
	/**
	 * @function back
	 * @param {Object} options
	 */
	back : function(options) {
		app.views.viewport.setActiveItem(0, options.animation);
	},

	/**
	 * Renders workspace.<br/>
	 * Clears all info (Search, Info, etc.)
	 * 
	 * @param options
	 */
	renderWorkspace : function(options) {
		app.views.mapView.setShowHint(false);
		app.views.viewport.setActiveItem(app.views.mapView, options.animation);
		var id = options.id;
		var workspace = NG.stores.workspace.getById(id);
		
		//First Login to server
		var session = NGServiceRequester.isAlreadyLoggedIn(workspace.getUsername(), workspace.getLoginUrl());
		if (session) {
			app.views.mapView.setSessionID(session.getSessionID());
			app.views.mapView.renderWorkspace(workspace);
		} else {
			NGServiceRequester.login(workspace.getUsername(), workspace.getPassword(), workspace.getLoginUrl(), {
				loginSuccess: function(sessionID) {
					app.views.mapView.setSessionID(sessionID);
					app.views.mapView.renderWorkspace(workspace);
				},
				loginFail: function(req) {
					alert('Login Failed. Offline Mode.');
					app.views.mapView.setSessionID("");
					app.views.mapView.renderWorkspace(workspace);
				} 
			});
		}
		this.renderInitialize(workspace);
	},
	
	/**
	 * @private
	 * @param workspace
	 */
	renderInitialize: function (workspace){
	    if (app.getViewport()) {
	    	app.getViewport().getMapToolbarButton().setBadge(workspace.getName());
	    	app.getViewport().setSearchButtonBadgeText(null);
	    }	    	
	    app.views.searchView.clear();
	    
	},

	/**
	 * 
	 * @param {Object} options
	 */
	zoomIn : function(options) {
		options.map.zoomIn();
	},

	/**
	 * 
	 * @param {Object} options
	 */
	zoomOut : function(options) {
		options.map.zoomOut();
	},

	/**
	 * Shows map with zoom level 1.
	 * 
	 * @param {Object} options
	 */
	refresh : function(options) {
		options.map.zoomTo(1);
	},

	/**
	 * Shows categories list of recent project.
	 * @param {Object} options
	 */
	listCategories : function(options) {
		NG.views.CategorListOverlay({
			mapView : options.mapView,
			workspace : options.workspace
		}).show('pop');
	},

	/**
	 * Shows fad list of recent project.
	 * @param {Object} options
	 */
	listFAD : function(options) {
		NG.views.FADListOverlay({
			mapView : options.mapView,
			workspace : options.workspace
		}).show('pop');
	},
	
	/**
	 * Loads FAD list. If fad list is found in cache it is returned.
	 * <b>options</b> param consists of<br>
	 * <li>workspace: NG.models.Workspace
	 * <li>successFn: Function(FADList, sessionID)
	 * <li>failureFn: Function(response)
	 * 
	 * @param {Object} options
	 */
	loadFAD: function (options) {
		var workspace = options.workspace;
		
    	function doNCDDServices (ncddServicesCommand, sessionID){
			if (NGFADCache.containsKey(ncddServicesCommand.getCacheKey())) {
				var fadList = NGFADCache.get(ncddServicesCommand.getCacheKey());
        		if (Ext.isFunction(options.successFn)) {
        			options.successFn.call(this, fadList, sessionID);
        		}
			} else {
	    		NGServiceRequester.executeCommand(ncddServicesCommand, sessionID, {
	            	requestFinished: function (response) {
	            		NGLogger.info("loadFAD --> Finish NCDDServices ");
	            		var ncddServicesResponse = new NG.response.NCDDServices({
	            			xmlData: response
	            		});
	            		var fadList = ncddServicesResponse.getResultList();
						//Add into NGFADCache
	            		NGFADCache.add(ncddServicesCommand.getCacheKey(), fadList);
	            		if (Ext.isFunction(options.successFn)) {
	            			options.successFn.call(this, fadList, sessionID);
	            		}
	            	},
	            	requestFail: function (response) {
	            		if (Ext.isFunction(options.failureFn)) {
	            			options.failureFn.call(this, response);
	            		}
	            	}
	    		});			
			}    		
    	}
    	
		var ncddServicesCommand = new NG.command.NCDDServices({
			workspaceName: workspace.getName(),
        	runXmlUrl: workspace.getRunXmlUrl()
		});		    	
		
		var session = NGServiceRequester.isAlreadyLoggedIn(workspace.getUsername(), workspace.getLoginUrl());
		if (session) {
			doNCDDServices(ncddServicesCommand, session.sessionID);
		} else {
			NGServiceRequester.login(workspace.getUsername(), workspace.getPassword(), workspace.getLoginUrl(), {
				loginSuccess: function(sessionID) {
					doNCDDServices(ncddServicesCommand, sessionID);
				},
				loginFail: function(response) {
            		alert("MapViewController->loadFAD login failed.");					
				}
			});
		}			
	},
	
	/**
	 * 
	 * @param options
	 *            [{OpenLayers.LonLat},{OpenLayers.Geometry.Point},{string}] point string type reguler exp must be as "####,#### ####,#####"<br>
	 *            {String} htmlContent For marker callout content<br>
	 *            {boolean} clickable If marker is clickable true else false, default is true<br>
	 *            {boolean} center If true, when marker is added set map center to marker, default is true<br>
	 *            {String} title Popup window title.
	 *            {NG.models.InfoDetail} infoDetail InfoDetail record which is selected.
	 * @return {OpenLayers.NGMarker} marker
	 */
	addMarker : function(options) {
		options = Ext.apply({
			htmlContent: "Bilgi Bulunamadı",
			clickable: true,
			center: true
		}, options);
		var lonLat = null;
		var point = options.point;
		if (point instanceof OpenLayers.LonLat) {
			lonLat = point;
		} else if (point instanceof OpenLayers.Geometry.Point) {
			lonLat = new OpenLayers.LonLat(point.x, point.y);
		} else { // like a "123123,45454 56565,67676" string
			var x = point.split(" ")[0];
			var y = point.split(" ")[1];
			lonLat = new OpenLayers.LonLat(x, y);
		}
		options.lonLat = lonLat;

		var marker = this.createMarker(options);
		
		//marker.setType(options.type);
		app.views.mapView.markersLayer.addMarker(marker);
		
		if (options.center == true) {
			app.views.mapView.map.setCenter(lonLat, app.views.mapView.map.getZoom(), false, false);
			app.views.viewport.setActiveItem(1, options.animation);			
		}
		return marker;
	},
	
	/**
	 * Marker click function for popup. 
	 * It is called after click on geometry whose type is Point searched after getinfoex request.
	 * @param {Object} evt
	 */
	markerClick: function (evt){
		/*
		var layer = app.views.mapView.markersLayer;
        sameMarkerClicked = (layer == layer.selectedFeature);
        layer.selectedFeature = (!sameMarkerClicked) ? layer : null;
        
        for(var i=0; i < layer.map.popups.length; i++) {
            layer.map.removePopup(layer.map.popups[i]);
        }
        
        //this.layer.map.addPopup(this.createPopup());
        layer.map.addPopup(this.createPopup());

        OpenLayers.Event.stop(evt);
        */
		/*
        sameMarkerClicked = (this == this.layer.selectedFeature);
        this.layer.selectedFeature = (!sameMarkerClicked) ? this : null;
        */
		
		/*
        for(var i=0; i < this.layer.map.popups.length; i++) {
            this.layer.map.removePopup(this.layer.map.popups[i]);
        }
        
        if (this.popup)
        	this.popup.show();
        else
        */
		
		if (this.popup) {
			this.popup.show();
			this.layer.map.addPopup(this.popup, true);
		}
		else {
			var popup = this.createPopup();
			var infoDetail = this.infoDetail;
			if (popup)
				popup.arrangeDetailEvents(function (){
					Ext.dispatch({
						controller: app.controllers.infoView,
						action: 'viewDetailOfFAD',
						infoDetail: infoDetail,
						editable: false
					});
				});
	        this.layer.map.addPopup(popup, true);			
		} 

        OpenLayers.Event.stop(evt);		
	},

	createMarker : function(options) {
		options = Ext.apply({
			imageUrl : 'img/pinGreen.png',
			lonLat : new OpenLayers.LonLat(0, 0),
			showCoordinates: true,
			htmlContent: 'Html Content',
			title: 'Title',
			clickable: true,
			infoDetail: null //is null except infodetail (search view) selection
		}, options);
		
		var iconSize = DEFAULT_MARKER_SIZE;
		var iconOffset = this._markerOffset(options);
		//var description = '<table width="250px"><tr><td>Expected delay:</td><td>Unknown Severity</td></tr><tr><td>Start:</td><td>08/Jun 13:47</td></tr><tr><td>End:</td><td>24/Jun 20:00</td></tr></table>';
		var data = {
			popupContentHTML:  '<h2>' + options.title + '</h2><p>' + options.htmlContent + '</p>',
			icon: new OpenLayers.Icon(options.imageUrl, iconSize, iconOffset)
		};
		var feature = new OpenLayers.Feature(app.views.mapView.markersLayer, options.lonLat, data);
		feature.popupClass = OpenLayers.Popup.Anchored;
		feature.infoDetail = options.infoDetail;
        var marker = feature.createMarker();
        
        if (options.clickable === true) {
            marker.events.register('click', feature, this.markerClick );
            marker.events.register('touchend', feature, this.markerClick );        	
        }
		return marker;
	},
	
	
	/**
	 * Calculates marker offset according to marker icon.
	 * @private
	 */
	_markerOffset: function (options) {
		var size = DEFAULT_MARKER_SIZE;
		var offset = null;
		if (options.imageUrl.indexOf("pin") >= 0)
			offset = new OpenLayers.Pixel(-(size.w / 2) + 10, -size.h);
		else if (options.imageUrl.indexOf("marker-blue.png") >= 0) {
			size = MARKER_BLUE_SIZE;
			offset = new OpenLayers.Pixel(-(size.w / 2), -size.h);			
		} else {
			offset = new OpenLayers.Pixel(-(size.w / 2), -size.h);
		}
		return offset;
	},
	
	
	/**
	 * 
	 * @param params<br>
	 *            {OpenLayers.LonLat} lonLat default value is (0, 0) <br>
	 *            {String} imageUrl default value is img/pinGreen.png<br>
	 *            {boolean} showCoordinates default value is true<br>
	 *            {boolean} clickable default value is true<br>
	 * @return {OpenLayers.NGMarker} marker
	 */
	createMarker1 : function(options) {
		options = Ext.apply({
			imageUrl : 'img/pinGreen.png',
			lonLat : new OpenLayers.LonLat(0, 0),
			showCoordinates: true,
			htmlContent: '',
			clickable: true
		}, options);
		var size = DEFAULT_MARKER_SIZE;
		var offset = null;
		/*
		if (options.imageUrl.indexOf("pin") >= 0)
			offset = new OpenLayers.Pixel(-(size.w / 2) + 10, -size.h);
		else if (options.imageUrl.indexOf("marker-blue.png") >= 0) {
			size = MARKER_BLUE_SIZE;
			offset = new OpenLayers.Pixel(-(size.w / 2), -size.h);			
		} else {
			offset = new OpenLayers.Pixel(-(size.w / 2), -size.h);
		}
		*/
		options.imageUrl = 'img/pinGreen.png';
		offset = new OpenLayers.Pixel(-(size.w / 2) + 10, -size.h);
		
		var icon = new OpenLayers.Icon(options.imageUrl, size, offset);
		//var marker = new OpenLayers.NGMarker(options.lonLat, icon.clone());
		var marker = new OpenLayers.Layer.Text(options.lonLat, icon.clone());
		var htmlContent = options.htmlContent +
			'<br><div class="markeroverlay-coordinates">Koordinatlar <br>['  
				+ options.lonLat.lon + ', '
				+ options.lonLat.lat + ']</div>';
		if (options.clickable) {
			var feature = new OpenLayers.Feature(app.views.mapView.markersLayer, options.lonLat);
		    feature.closeBox = true;
		    feature.popupClass = OpenLayers.Class(OpenLayers.Popup.AnchoredBubble, {minSize: new OpenLayers.Size(NG_POPUP_WIDTH, NG_POPUP_HEIGHT) } );
		    feature.data.popupContentHTML = 'NetGis Popup<br>adşaldska<br>dakdşal';
		    feature.data.overflow = "hidden";			
			
			marker.events.register(Ext.is.Desktop ? "click" : "touchend", feature, function(evt) {
				
				if (this.popup == null) {
		            this.popup = this.createPopup(this.closeBox);
		            app.views.mapView.map.addPopup(this.popup);
		            this.popup.show();
		        } else {
		            this.popup.toggle();
		        }
		        OpenLayers.Event.stop(evt);
				
				/*
				var p = new OpenLayers.Popup.FramedCloud("pop",
				        options.lonLat,
				        null,
				        '<div>name: '+ " xxx " +'</div>',
				        null,
				        true
				        //,function() {  }
				        );
				app.views.mapView.map.addPopup(p);
				*/
				
				/*
				var overlay = null;
				if (marker.overlay == null) {
					overlay = new NG.util.Overlay({
						htmlContent: htmlContent,
						modal: false,
						addClose: true
					});				
					marker.setOverlay(overlay);
				} else {
					overlay = marker.getOverlay();
				}
				overlay.showBy(evt.currentTarget);
				*/
				OpenLayers.Event.stop(evt);
			});			
		}
		return marker;
	},
	
	/**
	 * <b>options</b> params consists of<br>
	 * <li> polygon: NG.models.NGPolygon
	 * 
	 * @param {Object} options
	 */
	drawPolygon: function(options) {
		//app.views.mapView.vectorLayer.drawFeature();
		var ctrl = app.views.mapView.polygonLayerControl;
		var coordinates = options.polygon.getCoordinates(); //elements' type is NG.models.NGCoordinate
		var components = [];
		
		for ( var i = 0; i < coordinates.length; i++) {
			if (coordinates[i].isValid())
				components.push(coordinates[i].createPoint());
		}
		/*
		components.push(new OpenLayers.Geometry.Point(494891.825869,4425779.598286));
		components.push(new OpenLayers.Geometry.Point(495313.819921,4426011.819864));
		components.push(new OpenLayers.Geometry.Point(494981.71809342,4426030.547411));
		*/
		var linearRing = new OpenLayers.Geometry.LinearRing(components);
        var polygon = new OpenLayers.Geometry.Polygon([linearRing.clone()]);
        ctrl.drawFeature(polygon);
		app.views.viewport.setActiveItem(1, options.animation);
        var centerOfPolygon = linearRing.getCentroid();
		app.views.mapView.map.setCenter(
				new OpenLayers.LonLat(centerOfPolygon.x, centerOfPolygon.y), 
				app.views.mapView.map.getZoom(), 
				false, 
				false);
	},
	
	/**
	 * Draws path on map. It is invoked from shortestfind.<br>
	 * <b>options</b> param consists of 
	 * <li>pointArray: Array. [openlayes.Geometry.Point]
	 * 
	 * @param {Object} options
	 */
	drawPath: function(options) {
		//app.views.mapView.vectorLayer.drawFeature();
		var ctrl = app.views.mapView.pathLayerControl;
		var lineLayer = ctrl.layer;
		
		var components = options.pointArray;
        var line = new OpenLayers.Geometry.LineString(components);
        var style = {
    		strokeColor: app.getSettings().getLineColor(), 
    		strokeOpacity: "0.7", 
    		strokeWidth: 4, 
    		fillColor: app.getSettings().getLineColor(), 
    		pointRadius: 5, 
    		cursor: "pointer"
        };
        //alert(ctrl.drawFeature);
        //ctrl.handler.style = style;
        var lineFeature = new OpenLayers.Feature.Vector(line, null, style);
        lineLayer.addFeatures([lineFeature]);
        
        //ctrl.drawFeature(line, style);
		app.views.viewport.setActiveItem(1, options.animation);
        var centerOfPolygon = line.getCentroid();
		app.views.mapView.map.setCenter(
				new OpenLayers.LonLat(centerOfPolygon.x, centerOfPolygon.y), 
				app.views.mapView.map.getZoom(), 
				false, 
				false);		
	},
	
	/**
	 * Geolocation.
	 * @param {Object} options
	 */
	locate: function (options){
        var geolocate = app.views.mapView.geolocate;
        if (geolocate.active) {
            geolocate.getCurrentLocation();
        } else {
            geolocate.activate();
        }
        NGLogger.info("Geolocate request sent.");
	},
	
	/**
	 * <b>options</b> param consists of
	 * <li>path: OpenLayers.Geometry.LineString
	 * 
	 * @param {Object} options 
	 * 		
	 */
	shortestFind: function (options){
		var path = options.path;
		var startPoint = path.getVertices()[0];
		var finishPoint = path.getVertices()[path.getVertices().length - 1];		
		var workspace = app.views.mapView.workspace;

		function doShortestFind(networkInfo, sessionID){
			if (Ext.isEmpty(networkInfo.getNetwork().getNetworkName())) {
				alert("Network İsmi boş.");
				return;
			}
			var shortestFindCommand = new NG.command.ShortestFind({
				networkInfo: networkInfo,
				startPoint: startPoint,
				finishPoint: finishPoint,
				workspaceName: workspace.getName(),
				runXmlUrl: workspace.getRunXmlUrl()
			});		
			NGLogger.info("SHORTESTFINDDATAXML:\n" + shortestFindCommand.getDataXML());
    		NGServiceRequester.executeCommand(shortestFindCommand, sessionID, {
            	requestFinished: function (response) {
            		NGLogger.info("Finish ShortestFindCommand: " + response);
            		var shortestFindResponse = new NG.response.ShortestFind({
            			xmlData: response
            		});
            		//alert(shortestFindResponse.getCoordinates());
            		app.controllers.mapView.drawPath({
            			pointArray: shortestFindResponse.getCoordinates()
            		});
            	},
            	requestFail: function (response) {
            		NGLogger.info("Fail ShortestFindCommand: " + response);
            		app.controllers.mapView.removeMarkers({
            			mapView: app.views.mapView,
            			type: 'path'
            		});
            	}
    		});			
		}
		
		function doNetworkInfo(command, sessionId) {
			if (NGNetworkInfoCache.containsKey(networkInfoCommand.getCacheKey())) {
				var networkInfo = NGNetworkInfoCache.get(networkInfoCommand.getCacheKey());
				doShortestFind(networkInfo, sessionId);
			} else {
				NGServiceRequester.executeCommand(command, sessionId, {
					requestFinished: function (response) {
						var networkInfo = command.getResponse(response).getNetworkInfo();
						
						//Add into NGNetworkInfoCache
						NGNetworkInfoCache.add(command.getCacheKey(), networkInfo);
						
						doShortestFind(networkInfo, sessionId);
					}
				});				
			}			
		}
		
		//Get networkInfo
		var networkInfoCommand = new NG.command.NetworkInfo({
			workspaceName: workspace.getName(),
			runXmlUrl: workspace.getRunXmlUrl()			
		});
		
		var session = NGServiceRequester.isAlreadyLoggedIn(workspace.getUsername(), workspace.getLoginUrl());
		if (session) {
			doNetworkInfo(networkInfoCommand, session.sessionID);
		} else {
			NGServiceRequester.login(workspace.getUsername(), workspace.getPassword(), workspace.getLoginUrl(), {
				loginSuccess: function(sessionID) {
					doNetworkInfo(networkInfoCommand, sessionID);
				},
				loginFail: function(response) {
					alert("Login Fail");
				}
			});
		}
	},
	
	/**
	 * Removes markers from map. If options.type is empty all markers are removed from map.<b>
	 * <b>options</b> param consists of<br>
	 * <li>mapView: NG.views.MapView
	 * <li>type: String. Type of marker, markers whose type is type are removed. 
	 * 
	 * @param {Object} options
	 */
	removeMarkers: function (options) {
		var markersLayer = options.mapView.markersLayer;
		var deleteArray = [];
		while (markersLayer.markers.length > 0) {
			var marker = markersLayer.markers[0];
			if (!Ext.isEmpty(options.type)) {
				if (marker.getType() == options.type) {
					deleteArray.push(marker);
				}
			} else {
				markersLayer.removeMarker(marker);					
			}
		}
		for ( var i = 0; i < deleteArray.length; i++) {
			markersLayer.removeMarker(deleteArray[i]);			
		}
	},
	
	/**
	 * Removes feature from drawing layers; point, polygon and point.
	 * <b>options</b> param consists of<br>
	 * <li>mapView: NG.views.MapView
	 * 
	 * @param {Object} options
	 * 		
	 */
	removeAllFeaturesFromDrawingLayers: function (options){
		var mapView = options.mapView;
		var lpoint = mapView.pointLayerControl.layer;
		var lpolygon = mapView.polygonLayerControl.layer;
		var lpath = mapView.pathLayerControl.layer;
		
		lpoint.removeAllFeatures();
		lpolygon.removeAllFeatures();
		lpath.removeAllFeatures();
	},
	
	/**
	 * When settings changed this method is called by settings controller.
	 * @param {Object} options
	 */
	settingsChanged: function (options) {
		app.controllers.mapView.doZoomControl(options);
		if (Ext.isEmpty(app.views.mapView.map))
			return;
		app.views.mapView.setOffline(options.settings.offlineEnabled());
	},
	
	/**
	 * @private
	 */
	ZOOM_CONTROL_ID: "ng-zoom-control-id",
	
	/**
	 * According to settings, openlayers zoom control is added or removed from map view.<br>
	 * <b>options</b> param consists of<br>
	 * <li>settings: NG.models.Settings
	 * 
	 * @param {Object} options 
	 */
	doZoomControl: function (options) {
		var settings = options.settings;
		//If map is not rendered exit from method
		if (Ext.isEmpty(app.views.mapView.map))
			return;
		if (settings.showZoomControl()) {
			var zoomControl = new OpenLayers.Control.ZoomPanel({
				id: this.ZOOM_CONTROL_ID 
			});
			app.views.mapView.map.addControl(zoomControl);
		} else {
			var zoomControl = app.views.mapView.map.getControl(this.ZOOM_CONTROL_ID);
			if (zoomControl != null)
				app.views.mapView.map.removeControl(zoomControl);			
		}
	},
	
	
	/**
	 * Handles putinfoex operation.<br>
	 * <b>options</b> param consists of<br>
	 * <li>workspace: NG.models.Workspace
	 * 
	 * @param {Object} options
	 */
	putInfo:function (options){
		
		var workspace = options.workspace;
		var session = NGServiceRequester.isAlreadyLoggedIn(workspace.getUsername(), workspace.getLoginUrl());
		
		var putinfoCommand = new NG.command.PutInfoEx({
			workspaceName: workspace.getName(),
			isValidUrl: workspace.getIsValidUrl()
		});	
		
		var cacheKeyIsValid = putinfoCommand.getIsValidCacheKey() + "-" + session.getSessionID();
		if (NGISVALIDCache.containsKey(cacheKeyIsValid)) {
			var validity = NGISVALIDCache.get(cacheKeyIsValid);
    		if (validity) {
    			this.doPutInfoExForInsert();
    			return;
    		}
		}
		
		NGServiceRequester.executeCommand(putinfoCommand, session.getSessionID(), {
	    	requestFinished: function (response) {
	    		var validity = putinfoCommand.isValid(response);
	    		if (validity) {
	    			//put it into cache
	    			if (!NGISVALIDCache.containsKey(cacheKeyIsValid)) {
	    				NGISVALIDCache.add(cacheKeyIsValid, validity);
	    			}

	    			app.controllers.mapView.doPutInfoExForInsert();
	    		} else {
	    			alert("Operation is not allowed.");
	    		}
	    	}
	    });
	},
	
	/**
	 * Shows form of the fad to be inserted.
	 * @private
	 * @param polygon
	 */
	doPutInfoExForInsert: function (){
		
    	//var selectedFAD = app.views.mapView.getSelectedFAD();
    	var selectedCategory = app.views.mapView.getSelectedCategory();
    	if (Ext.isEmpty(selectedCategory)) {
    		alert(MSG_SELECT_CATEGORY);
    		return;
    	}
    	
    	NGLogger.info("Selected Category: " + selectedCategory.getRefName());
    	
    	var successFn = function (selectedFAD, sessionID){
        	if (Ext.isEmpty(selectedFAD)) {
        		alert(MSG_FAD_NOT_FOUND_FOR_CATEGORY);
        		return;
        	}
    		
    		var workspace = app.views.mapView.workspace;
    		
    		if (selectedCategory.isGeoPolygon()) {
    			alert('Ekranda poligon çiziniz');
        		app.views.mapView.setMode(MAP_MODE_INFO_POLYGON);    			
        		var temp = app.views.mapView.polygonLayerControl.callbacks.done;
        		
        		app.views.mapView.polygonLayerControl.callbacks.done = function (polygon){
        			try {
        				var form = new NG.info().initForm({
        					insert: true,
        					editable: true,
        					polygon: polygon,
        					selectedFAD: selectedFAD,
        					sessionID: sessionID
        				});
        				if (form) {
        		    		form.show();	    			
        				}
        			} catch(e){
        				console.log(e);
        			} finally{
        				app.views.mapView.setMode(MAP_MODE_NAV);
        				app.views.mapView.polygonLayerControl.callbacks.done = temp;
        			}
        		};
    		} else if (selectedCategory.isGeoPath()) {
    			alert('Ekranda yol çiziniz');
        		app.views.mapView.setMode(MAP_MODE_INFO_PATH);
        		var temp = app.views.mapView.pathLayerControl.callbacks.done;
        		
        		app.views.mapView.pathLayerControl.callbacks.done = function (path){
        			try {
        				var form = new NG.info().initForm({
        					insert: true,
        					editable: true,
        					polygon: path,
        					selectedFAD: selectedFAD,
        					sessionID: sessionID
        				});
        				if (form) {
        		    		form.show();	    			
        				}
        			} catch(e){
        				console.log(e);
        			} finally{
        				app.views.mapView.setMode(MAP_MODE_NAV);
        				app.views.mapView.pathLayerControl.callbacks.done = temp;
        			}
        		};        		
        		
    		} else if (selectedCategory.isGeoPoint()) {
    			alert('Ekranda nokta seçiniz');
        		app.views.mapView.setMode(MAP_MODE_INFO_POINT);    			    			
        		var temp = app.views.mapView.pointLayerControl.callbacks.done;

        		app.views.mapView.pointLayerControl.callbacks.done = function (point){
        			try {
        				var form = new NG.info().initForm({
        					insert: true,
        					editable: true,
        					polygon: point,
        					selectedFAD: selectedFAD,
        					sessionID: sessionID
        				});
        				if (form) {
        		    		form.show();	    		
        				}
        			} catch(e){
        				console.log(e);
        			} finally{
        				app.views.mapView.setMode(MAP_MODE_NAV);
        				app.views.mapView.pointLayerControl.callbacks.done = temp;
        			}
        		};        		
    		}
    	};
    	
    	var failureFn = function (message){
    		alert(message);
    	};
    	
    	selectedCategory.findFAD({
    		successFn: successFn,
    		failureFn: failureFn
    	});
		
	},
	
	/**
	 * InfoView calls this methods.
	 * <b>options</b> params consists of<br>
	 * <li>workspace: NG.model.Workspace
	 * <li>delegator: //TODO 
	 * 
	 * @param {NG.command.NCDDServices} ncddServicesCommand
	 * @param {String} sessionID
	 * @param {Object} options
	 */
	doNCDDServices: function (ncddServicesCommand, sessionID, options){
		var workspace = options.workspace;
		
		//Is there any selected FAD from the FAD list.
		if (!Ext.isEmpty(app.views.mapView.getSelectedFAD())) {
			var fadList = [];
			fadList.push(app.views.mapView.getSelectedFAD());
			
			if (options.delegator && Ext.isFunction(options.delegator)) {
				options.delegator.call(options.delegator, fadList, sessionID, options); //buradan daha sonra response'u dön
			}
		}
		else if (NGFADCache.containsKey(ncddServicesCommand.getCacheKey())) {
			var fadList = NGFADCache.get(ncddServicesCommand.getCacheKey());
			
			if (options.delegator && Ext.isFunction(options.delegator)) {
				options.delegator.call(options.delegator, fadList, sessionID, options); //buradan daha sonra response'u dön
			}
			
		} else {
    		NGServiceRequester.executeCommand(ncddServicesCommand, sessionID, {
            	requestFinished: function (response) {
            		NGLogger.info("Finish NCDDServices: ");
            		var ncddServicesResponse = new NG.response.NCDDServices({
            			xmlData: response
            		});
            		var fadList = ncddServicesResponse.getResultList();
					//Add into NGFADCache
            		
        			if (options.delegator && Ext.isFunction(options.delegator)) {
        				options.delegator.call(options.delegator, fadList, sessionID, options); //buradan daha sonra response'u dön
        			}
        			
        			NGFADCache.add(ncddServicesCommand.getCacheKey(), fadList, options);
            	},
            	requestFail: function (response) {
            		alert("NCDDServices isteği başarısız.");
            	}
    		});			
		} 
		
	},		
	
	/**
	 * <b>options</b> params consists of<br>
	 * <li> getinfoex: NG.command.GetInfoExt
	 * 
	 * @param {Array} fadList //TODO fad listesindeki nesnelerin sınıfını belirts
	 * @param {String} sessionID
	 * @param {Object} options
	 * 		
	 */
	doGetInfoEx: function (fadList, sessionID, options) {
		var workspace = options.workspace;
		
		/*
		var getinfoex = new NG.command.GetInfoEx({
			workspace: workspace,
			runXmlUrl: workspace.getRunXmlUrl(),
			workspaceName: workspace.getName(),
			SRID: '', //workspace.getSRID(),
			proj: '',
			FAD: fadList,
			clockwise: 'False',
			countOnly: fadList.length === 1 ? 'False' : 'True',
			intersects: options.intersects
		});
		*/

		var getinfoex = options.getinfoex;
		getinfoex.FAD = fadList;
		getinfoex.countOnly = fadList.length === 1 ? 'False' : 'True',
		
		//alert(getinfoex.getDataXML());

				
		//Show info list panel
		app.getViewport().activateSearchView(options);

		NGServiceRequester.executeCommand(getinfoex, sessionID, {
	    	requestFinished: function (response) {
	    		var getInfoExResponse = getinfoex.getResponse(response);
	    		var infoList = getInfoExResponse.getInfoList();
	    		
	    		if (getinfoex.countOnly === 'False') { //A Fad is selected from FAD list
	    			//TODO bu işlemi controller'a taşı
	    	    	app.views.searchView.prepareForNewDetailSearch();
	    	    	if (infoList && infoList.length >=1) {
        	    		var detailList = infoList[0].getDetailList();
        	    		for ( var i = 0; i < detailList.length; i++) {
    						detailList[i].prepareHTMLContent();
    					}
        	    		infoList[0].setRowsCount(detailList.length);
        	    		app.views.searchView.renderInfoDetailList(detailList);    	    	    		
	    	    	} else {
	    	    		app.views.searchView.infoDetailList.clear();
	    	    	}
	    		} else {
    	    		Ext.dispatch({
    	    			controller: app.controllers.searchView,
    	    			action: 'listInfoList',
    	    			infoList: infoList,
    	    			getInfoExCommand: getinfoex
    	    		});    	    			
	    		}
	    	}
	    });
	},
	
	/**
	 * Point and Polygon search.
	 * <b>options</b> param consists of<br>
	 * <li>workspace: NG.models.Workspace
	 * <li>getinfoext: NG.command.GetInfoEx
	 * <li>intersects: Object. Form of <b>Geometry.polygon.coordinates</b>
	 * 
	 * @param {Object} options
	 */
	getInfoEx: function (options) {
		app.views.searchView.prepareForNewSearch();
		
		var workspace = options.workspace;
		options.delegator = app.controllers.mapView.doGetInfoEx;
		
		var ncddServicesCommand = new NG.command.NCDDServices({
			workspaceName: workspace.getName(),
        	runXmlUrl: workspace.getRunXmlUrl()
//			isValidUrl: workspace.getIsValidUrl()
		});
		
		if (!options.getinfoex) {
			options.getinfoex = new NG.command.GetInfoEx({
				workspace: workspace,
				runXmlUrl: workspace.getRunXmlUrl(),
				workspaceName: workspace.getName(),
				SRID: '', //workspace.getSRID(),
				proj: '',
				//FAD: fadList,
				clockwise: 'False',
				//countOnly: fadList.length === 1 ? 'False' : 'True',
				intersects: options.intersects
			});
		}
		
		var session = NGServiceRequester.isAlreadyLoggedIn(workspace.getUsername(), workspace.getLoginUrl());
		if (session) {
			this.doNCDDServices(ncddServicesCommand, session.sessionID, options);
		} else {
			NGServiceRequester.login(ws.getUsername(), workspace.getPassword(), workspace.getLoginUrl(), {
				loginSuccess: function(sessionID) {
					app.controllers.mapView.doNCDDServices(ncddServicesCommand, sessionID, options);
				},
				loginFail: function(response) {
					alert("Login Failed");
				}
			});
		}
	},
	
	doGetLookupXml : function (options) {
		
	},
	
	lookupXml : function(options) {
		var workspace = options.workspace;
		options.delegator = app.controllers.mapView.doGetLookupXml;
		
		var lookupReq = new NG.command.GetLookupXml({
			workspace: workspace,
			runXmlUrl: workspace.getRunXmlUrl(),
			workspaceName: workspace.getName(),
			keyField: "DURUM_TIPI",
			valueField: "OBJECTID",
			tableName: "BAGLANTI1.LOOKUP_DURUM"
		});
		
		var session = NGServiceRequester.isAlreadyLoggedIn(workspace.getUsername(), workspace.getLoginUrl());
		if (session) {

    		NGServiceRequester.executeCommand(lookupReq, session.getSessionID(), {
            	requestFinished: function (response) {
            		
            		var lookupResponse = new NG.response.GetLookupXml({
            			xmlData: response
            		});

            	},
            	requestFail: function (response) {
            		alert("lookup failed!");
            	}
    		});			
			
		}
	},
	
	/**
	 * Distance measurement and area calculation operations are done.<br>
	 * This delegatore is set in mapView panel.<br>
	 * <b>event</b> param consists of<br>
	 * <li>geometry: //TODO tipleri yaz
	 * <li>units: 
	 * <li>order: 
	 * <li>measure: 
	 * 
	 * @param {Objet} event
	 */
    handleMeasurements: function (event) {
        var geometry = event.geometry;
        var units = event.units;
        var order = event.order;
        var measure = event.measure;
        //var element = document.getElementById('output');
        var out = "";
        if(order == 1) {
            out += "measure: " + measure.toFixed(3) + " " + units;
        } else {
            out += "measure: " + measure.toFixed(3) + " " + units + "<sup>2</" + "sup>";
        }
        
        var measureInfoPanel = NG.measureInfo(out);
        measureInfoPanel.update(out);
        measureInfoPanel.show();
    },
    
    /**
     * Shows layers of map shown on recently. 
     * 
     * @param {Object} options
     */
    wmsLayers: function (options){
    	if (!app.popup) {
            app.popup = new Ext.Panel({
                floating: true,
                modal: true,
                centered: true,
                hideOnMaskTap: true,
                width: 240,
                items: [{
                    xtype: 'netgis-WMSList',
                    map: app.views.mapView.map
                }],
                scroll: 'vertical'
            });
        }
        app.popup.show('pop');    	
    }
});


/**
 * Global singleton variable. This controller is instance of NG.controllers.MapView.
 * 
 * @singleton app.controllers.mapView
 * @type  NG.controllers.MapView
 */
app.controllers.mapView = new NG.controllers.MapView();